package com.casa_apoio.controller;

import com.casa_apoio.model.dao.AcessoDAO;
import com.casa_apoio.model.dao.FuncionarioDAO;
import com.casa_apoio.model.dao.HospedagemDAO;
import com.casa_apoio.model.dao.HospedeDAO;
import com.casa_apoio.model.dao.LeitoDAO;
import com.casa_apoio.model.entity.Acesso;
import com.casa_apoio.model.entity.Funcionario;
import com.casa_apoio.model.entity.Hospedagem;
import com.casa_apoio.model.entity.Hospede;
import com.casa_apoio.model.entity.Leito;
import com.casa_apoio.util.FacesContextUtil;
import java.io.Serializable;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.RequestScoped;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;

@ManagedBean
@RequestScoped
public class MbHospedagem implements Serializable {

    private Hospedagem hospedagem = new Hospedagem();
    private List<Hospedagem> hospedagens;
    private List<Hospede> hospedes;
    private Integer idHospede;
    private String cpfHospede;
    private Hospede hospede;
    private Leito leito;
    private List<Leito> leitos;
    private int totalLeitos;
    private int leitosOcupados;
    private int leitoLivres;
    private int taxaOcupacao;

    private HospedagemDAO hospedagemDAO() {
        HospedagemDAO<Hospedagem> hospedagemDAO = new HospedagemDAO<Hospedagem>(Hospedagem.class, FacesContextUtil.getRequestSession());
        return hospedagemDAO;
    }

    private HospedeDAO hospedeDAO() {
        HospedeDAO<Hospede> hospedeDAO = new HospedeDAO<Hospede>(Hospede.class, FacesContextUtil.getRequestSession());
        return hospedeDAO;
    }

    private LeitoDAO leitoDAO() {
        LeitoDAO<Leito> leitoDAO = new LeitoDAO<Leito>(Leito.class, FacesContextUtil.getRequestSession());
        return leitoDAO;
    }

    private AcessoDAO acessoDAO() {
        AcessoDAO<Acesso> acessoDAO = new AcessoDAO<Acesso>(Acesso.class, FacesContextUtil.getRequestSession());
        return acessoDAO;
    }

    private FuncionarioDAO<Funcionario> funcionarioDAO() {
        FuncionarioDAO<Funcionario> funcionarioDAO = new FuncionarioDAO<Funcionario>(Funcionario.class, FacesContextUtil.getRequestSession());
        return funcionarioDAO;
    }

    private Funcionario usuarioLogado() {
        FacesContext context = FacesContext.getCurrentInstance();
        ExternalContext external = context.getExternalContext();
        String login = external.getRemoteUser();

        List<Acesso> lista = acessoDAO().verificaLogin(login);
        Acesso a = lista.get(0);
        Funcionario f = funcionarioDAO().getEntity(a.getFuncionario().getIdFuncionario());
        return f;
    }

    public String salvarHospedagem() {
        if (hospedagem.getIdHospedagem() == null || hospedagem.getIdHospedagem() < 1) {
            if (hospedagem.getLeito().getIdLeito() > 0) {
                if (hospedagem.getHospede().getIdHospede() > 0) {
                    hospedagem.setFuncionario(usuarioLogado());
                    hospedagemDAO().salvar(hospedagem);
                    ocuparLeito();
                    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Gravação efetuada com sucesso!", ""));
                } else {
                    FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Pacinete não foi carregado corretamente!", ""));
                }
            } else {
                FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, "Leito não foi selecionado!", ""));
                return null;
            }

        } else {
            hospedagemDAO().atualizar(hospedagem);
        }
        limparHospedagem();
        return "checkinHopedagem.faces";
    }

    private boolean verificaHospedagemNaoFinalizada() {
        if (idHospede > 0) {
            hospedagens = hospedagemDAO().verificaHospedagemHospedeId(idHospede);
        } else if (!cpfHospede.isEmpty()) {
            hospedes = hospedeDAO().buscarHospedePorCPF(cpfHospede);
            hospede = hospedes.get(0);
            hospedagens = hospedagemDAO().verificaHospedagemHospedeId(hospede.getIdHospede());
        }

        if (hospedagens.size() > 0) {
            hospedagem = hospedagens.get(0);
            FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_WARN, "Hospedagem não finalizada para: " + hospedagem.getHospede().getNome(), ""));
            hospedagem = null;
            return false;
        } else {
            return true;
        }
    }

    private void ocuparLeito() {
        leito = (Leito) leitoDAO().getEntity(hospedagem.getLeito().getIdLeito());
        leito.setOcupado(true);
        leitoDAO().atualizar(leito);
    }

    public String checkOutHospedagem(Hospedagem hospedagem) {
        Calendar c = Calendar.getInstance();
        int hora = c.get(Calendar.HOUR_OF_DAY);
        int min = c.get(Calendar.MINUTE);
        String h = String.valueOf(hora);
        String m = String.valueOf(min);

        hospedagem.setDataSaida(new Date());
        hospedagem.setHoraSaida(h + ":" + m);
        try {
            hospedagemDAO().atualizar(hospedagem);
            leito = (Leito) leitoDAO().getEntity(hospedagem.getLeito().getIdLeito());
            leito.setOcupado(false);
            leitoDAO().atualizar(leito);
        } catch (Exception e) {
        }
        limparHospedagem();
        return null;
    }

    public String checkinHospede() {
        System.out.println(">>>>> Id do Hospede.:" + idHospede + " <<<<<<");
        if (verificaHospedagemNaoFinalizada()) {
            Calendar c = Calendar.getInstance();
            int hora = c.get(Calendar.HOUR_OF_DAY);
            int min = c.get(Calendar.MINUTE);
            String h = String.valueOf(hora);
            String m = String.valueOf(min);

            if (idHospede > 0 || (!cpfHospede.isEmpty())) {
                try {
                    if (idHospede > 0) {
                        hospede = (Hospede) hospedeDAO().getEntity(idHospede);
                    } else {
                        hospedes = hospedeDAO().buscarHospedePorCPF(cpfHospede);
                        hospede = hospedes.get(0);
                    }

                } catch (Exception e) {
                    throw new ExceptionInInitializerError(e);
                }

                if (hospede != null) {
                    System.out.println("Carregr Hospede.:" + hospede.getIdHospede());
                    hospedagem.setHospede(hospede);
                    hospedagem.setDataEntrada(new Date());
                    hospedagem.setHoraEntrada(h + ":" + m);
                    hospedagem.setCidade(hospede.getCidade());
                    idHospede = null;
                    cpfHospede = null;
                } else {
                    FacesContext.getCurrentInstance().addMessage("carregaHospede:msg_ph", new FacesMessage(FacesMessage.SEVERITY_INFO, "Paciente não encontrado!", ""));
                    idHospede = null;
                    cpfHospede = null;
                    limparHospedagem();
                }
            } else {
                FacesContext.getCurrentInstance().addMessage("carregaHospede:msg_ph", new FacesMessage(FacesMessage.SEVERITY_INFO, "Digite o codigo ou cpf do paciente", ""));
            }
        } else {
            return null;
        }
        return "checkinHopedagem.faces";
    }

    public String alterarHospedagem(Hospedagem hospedagem) {
        limparHospedagem();
        hospedagem = null;
        return "checkinHopedagem.faces";
    }

    public String limparHospedagem() {
        hospedagem = new Hospedagem();
        hospede = null;
        leito = null;
        hospedagens = null;
        return "checkinHopedagem.faces";
    }

    public Hospedagem getHospedagem() {
        if (hospedagem == null) {
            hospedagem = new Hospedagem();
        }
        return hospedagem;
    }

    public void setHospedagem(Hospedagem hospedagem) {
        this.hospedagem = hospedagem;
    }

    public List<Hospedagem> getHospedagens() {
        if (hospedagens == null) {
            hospedagens = hospedagemDAO().listaHospedagem();
        }

        leitos = leitoDAO().listaLeito();

        totalLeitos = leitos.size();
        leitoLivres = 0;
        leitosOcupados = 0;
        for (Leito l : leitos) {
            if (l.isOcupado()) {
                leitosOcupados += 1;
            } else {
                leitoLivres += 1;
            }
            taxaOcupacao = ((leitosOcupados) * 100) / totalLeitos;
        }

        return hospedagens;
    }

    public void setHospedagens(List<Hospedagem> hospedagens) {
        this.hospedagens = hospedagens;
    }

    public Integer getIdHospede() {
        return idHospede;
    }

    public void setIdHospede(Integer idHospede) {
        this.idHospede = idHospede;
    }

    public Hospede getHospede() {
        return hospede;
    }

    public void setHospede(Hospede hospede) {
        this.hospede = hospede;
    }

    public String getCpfHospede() {
        return cpfHospede;
    }

    public void setCpfHospede(String cpfHospede) {
        this.cpfHospede = cpfHospede;
    }

    public List<Hospede> getHospedes() {
        return hospedes;
    }

    public void setHospedes(List<Hospede> hospedes) {
        this.hospedes = hospedes;
    }

    public Leito getLeito() {
        return leito;
    }

    public void setLeito(Leito leito) {
        this.leito = leito;
    }

    public List<Leito> getLeitos() {
        return leitos;
    }

    public void setLeitos(List<Leito> leitos) {
        this.leitos = leitos;
    }

    public int getTotalLeitos() {
        return totalLeitos;
    }

    public void setTotalLeitos(int totalLeitos) {
        this.totalLeitos = totalLeitos;
    }

    public int getLeitosOcupados() {
        return leitosOcupados;
    }

    public void setLeitosOcupados(int leitosOcupados) {
        this.leitosOcupados = leitosOcupados;
    }

    public int getLeitoLivres() {
        return leitoLivres;
    }

    public void setLeitoLivres(int leitoLivres) {
        this.leitoLivres = leitoLivres;
    }

    public int getTaxaOcupacao() {
        return taxaOcupacao;
    }

    public void setTaxaOcupacao(int taxaOcupacao) {
        this.taxaOcupacao = taxaOcupacao;
    }
}
